﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Data;
using System.Data.Objects.DataClasses;
using System.Linq.Expressions;
using System.Threading;
using System.Web;
using KandaAlpha.Domain.Model.Entities;
using KandaAlpha.Domain.Repository;

namespace KandaAlpha.Infrastructure.Repository.EF
{
    public class GenericRepository<T> : IGenericRepository<T> where T : EntityBase
    {

        /// <summary>
        /// Returns the active object context
        /// </summary>
        private ObjectContext ObjectContext
        {
            get
            {
                return ObjectContextManager.GetObjectContext();
            }
        }

        public T Load(Expression<Func<T, bool>> whereCondition)
        {
            return default(T);
        }

        public IQueryable<T> GetQuery()
        {
            // TODO Check this works with inheritance
            return this.ObjectContext.CreateObjectSet<T>();
        }

        /// <summary>
        /// Provides explicit loading of object properties (EF v4.0 feature)
        /// </summary>
        public void LoadProperty(T entity, Expression<Func<T, object>> selector)
        {
            this.ObjectContext.LoadProperty(entity, selector);
        }

        public List<T> GetAll()
        {
            return GetQuery().ToList();
        }

        public void Add(T entity)
        {
            // TODO - check if this works
            this.ObjectContext.AddObject(GetBaseType(typeof(T)).Name.ToString(), entity);
        }

        public void Update(T entity)
        {
            // nothing to do here
        }

        public void Delete(T entity)
        {
            this.ObjectContext.DeleteObject(entity);
        }

        private static Type GetBaseType(Type type)
        {
            Type baseType = type.BaseType;
            if (baseType != null && baseType != typeof(EntityBase))
            {
                return GetBaseType(type.BaseType);
            }
            return type;
        }

        private static bool HasBaseType(Type type, out Type baseType)
        {
            Type originalType = type.GetType();
            baseType = GetBaseType(type);
            return baseType != originalType;
        }

    }
}
